iT邦幫忙

2024 iThome 鐵人賽

DAY 7
0
Modern Web

創意前端設計:用 Vue.js 打造 30 個互動實用功能系列 第 7

Day07 Vue.js 簡單迷人的網頁動態效果 - 鉤子 Hooks 篇

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20240921/20124462KAWyKimbHp.jpg

讓網頁進場更優雅!深入 Vue.js Transition Hooks,搞定背景閃白問題!

大家好!今天要聊的是 Vue.js 的 Transition Hooks,這些小巧的鉤子不僅能讓網頁切換更順暢,還能在動效進行時插入各種巧妙的處理。

你是不是也曾遇過頁面切換時,背景突然閃白的尷尬情況?

沒關係,這篇文章不僅會帶你認識 Vue 的鉤子們,還會教你如何用實際案例解決這些常見問題,讓你的網頁更迷人、更專業!
準備好讓你的動態效果升級嗎?
我們一起來看看吧!


img

處理鉤子(Hooks)的執行順序

在上一篇的文章範例中,Day06 Vue.js 簡單迷人的網頁動態效果 - 過渡類別篇
我們就有使用過渡模式,來搭配往左滑的換頁效果,這次我們改採用往上滑頁效果的方式來繼續說明。


<template>
	<div :class="['relative w-full h-screen overflow-hidden', containerBgColor]">
		<transition name="slide" mode="out-in">
			<component :is="getComponent" @change-page="changePage" />
		</transition>
	</div>
</template>
<style scoped>
/* 調整進場與離場動效為上下方向 */
.slide-enter-from {
  transform: translateY(100%); /* 從下方進場 */
}

.slide-enter-active,
.slide-leave-active {
  position: absolute;
  width: 100%;
  transition: transform 0.5s ease; /* 過渡時間與緩動 */
}

.slide-leave-to {
  transform: translateY(-100%); /* 向上滑出 */
}

.slide-enter-to,
.slide-leave-from {
  transform: translateY(0); /* 元素在正中間位置 */
}
</style>

在過渡效果中,過渡模式(Transition Mode)決定了鉤子的執行順序,直接影響動效的協調與體驗。

  • mode="in-out":先完成進場動效,再執行離場動效。適合強調新內容的模式。
  • mode="out-in":先完成離場動效,再執行進場動效。適合先清除舊內容的場景。

在使用 mode="out-in"mode="in-out" 時,這兩個模式是互相排斥的,可以根據具體的過場需求來選擇,因為這兩種模式會有不同的視覺體驗效果。

我們使用 mode="in-out" 做 Page Transition 時,換頁過程中常見的「畫面閃白」問題,我們的處理方法很簡單——先存下當前頁面的背景色,下一次換頁時直接延續這個顏色!

這樣就不會出現突然空白的突兀感,換頁自然又順暢呢


過渡組件中的鉤子們(Hooks)

<Transition
  @before-enter="onBeforeEnter"
  @enter="onEnter"
  @after-enter="onAfterEnter"
  @enter-cancelled="onEnterCancelled"
  @before-leave="onBeforeLeave"
  @leave="onLeave"
  @after-leave="onAfterLeave"
  @leave-cancelled="onLeaveCancelled"
>
  <!-- ... -->
</Transition>

Vue 3 的 <transition> 元件提供了一系列的生命周期 hooks,用於在元素進場和離場的過程中掛鉤特定的操作。
這些 hooks 可以讓你在動效的不同階段執行自定義的邏輯。

進場動效 Hooks

  1. @before-enter="onBeforeEnter"(進場前):

    • 意思:元素在進場動效開始前觸發。在這個階段,你可以進行初始化設定,如添加初始狀態或隱藏元素。
    • 用途:用來設定進場動效的起始狀態。
  2. @enter="onEnter"(進場中):

    • 意思:元素進場動效開始時觸發。在這裡可以控制進場過程,比如設置動效效果、控制動效時間等。
    • 用途:在這個階段,可以觸發進場動效,改變元素的狀態或屬性。
  3. @after-enter="onAfterEnter"(進場後):

    • 意思:進場動效結束後觸發。這是動效完成後的狀態,通常用於清理或啟用動效結束後的行為。
    • 用途:動效完成後做一些後續處理,比如顯示內容或變更狀態。
  4. @enter-cancelled="onEnterCancelled"(進場取消):

    • 意思:當進場動效在進行中被取消時觸發(例如因為狀態改變或其他動效觸發導致當前動效被中止)。
    • 用途:處理被中止進場的狀況,重置或清除進場效果。

進場範例與實作程式碼

img

  • 進場程式碼

<script lang="ts" setup>
import { ref } from "vue";

const onBeforeEnter = () => {
  console.log(" @before-enter 進場動效開始了!");
};
// _el 忽略的參數表示我們知道這個參數存在但暫時不使用
// 這個參數仍然需要保留,因為它是 Vue Transition 鉤子的標準參數定義
const onEnter = (_el: Element, done: () => void) => {
  console.log(" @enter 進場動效活動!");
  done(); // 確保調用 done() 以通知 Vue 動效已完成
};

const onAfterEnter = () => {
  console.log(" @after-enter 進場動效已完成!");
};
// 控制元素顯示狀態
const show = ref(false);
</script>

<template>
  <div class="flex flex-col gap-4 mx-auto p-4 space-y-4">
    <button @click="show = !show" class="px-4 py-2 bg-blue-500 text-white text-10 rounded">
      進場動效範例觸發
    </button>

    <!-- 元素 1: 使用 before-enter -->
    <transition @before-enter="onBeforeEnter" :key="1">
      <div v-if="show" class="p-4 bg-yellow-200 rounded shadow">
        元素 1: @before-enter
      </div>
    </transition>

    <!-- 元素 2: 使用 enter -->
    <transition @enter="onEnter" :key="2">
      <div v-if="show" class="p-4 bg-green-200 rounded shadow">元素 2: @enter</div>
    </transition>

    <!-- 元素 3: 使用 after-enter -->
    <transition @after-enter="onAfterEnter" :key="3">
      <div v-if="show" class="p-4 bg-red-200 rounded shadow">元素 3: @after-enter</div>
    </transition>
  </div>
</template>

<style scoped>
</style>

離場動效 Hooks

  1. @before-leave="onBeforeLeave"(離場前):

    • 意思:元素在離場動效開始前觸發。通常用於設定離場前的初始狀態。
    • 用途:準備離場動效的狀態,比如將元素顯示為可見或其他狀態設定。
  2. @leave="onLeave"(離場中):

    • 意思:元素離場動效開始時觸發。在這個階段可以控制離場過程中的行為。
    • 用途:設置和控制離場動效,比如觸發動效效果或改變元素的狀態。
  3. @after-leave="onAfterLeave"(離場後):

    • 意思:離場動效結束後觸發。這是離場動效完成後的狀態,通常用於清理元素或執行後續行為。
    • 用途:在元素完成離場後進行處理,如清除元素、重置狀態等。
  4. @leave-cancelled="onLeaveCancelled"(離場取消):

    • 意思:當離場動效在進行中被取消時觸發。
    • 用途:處理被中止的離場情況,重置元素狀態或其他後續行為。

img

Hooks的回調函數, done() 的正確使用姿勢

  1. 什麼是 done()

    • done() 是一個回調函數,由 Vue 提供給進場或離場動效鉤子(如 @enter@leave 等)使用。它的作用是通知 Vue 當前的過渡動效已經完成,可以繼續下一步操作。
  2. done() 的必要性

    • 如果使用 CSS 進行動效,Vue 可以自動檢測動效結束(透過 CSS transition 或 animation 的結束事件),此時 done() 通常不需要手動調用。
    • 但在需要更精細控制的自定義動效中,Vue 無法自動檢測動效的結束。因此,必須手動調用 done(),告訴 Vue 動效已完成,否則 Vue 會無限等待動效的完成,導致動效行為卡住或其他過渡鉤子不會被執行。
  3. 使用 done() 的方式

    • 在鉤子中設置自定義動效效果,例如 @enter 中,當動效邏輯結束後,必須調用 done() 才能讓 Vue 繼續執行後續流程。

    • 例如,在 @enter 動效中,當動效完成後再執行 done(),如下:

      const onEnter = (el: Element, done: () => void) => {
        // 設定自定義動效,例如改變樣式或使用其他動效庫
        console.log(" @enter 進場動效活動!");
      
        // 模擬動效完成的延遲
        setTimeout(() => {
          done(); // 必須調用,否則 Vue 不會知道動效已完成
          console.log("進場動效結束");
        }, 1000); // 這裡的時間要與動效的實際時間對應
      };
      
  4. 典型的 done() 誤區

    • 忘記調用 done():這是最常見的問題,會導致動效狀態卡住
    • 提前調用 done():這會使動效未完成時就通知 Vue,導致動效被中斷或沒有正確顯示。

重點小結語

  • 鉤子的大秘密:Vue.js 的 Transition Hooks 讓網頁切換不只是動,還能加點小魔法!

  • 過渡模式小撇步:用 mode="in-out"mode="out-in" 決定誰先來、誰後走,換頁更流暢!

  • 閃白OUT!:換頁「閃白」不用怕!記得存下背景色,換頁時延續顏色,畫面超順超自然!

  • 進場&離場鉤子組合技:鉤子們一出手,各種進場、離場動態效果立刻安排起來!

  • done() 是個關鍵任務:動效過程完了要記得叫 done(),不然 Vue 會以為你還沒結束,動效會卡住哦!

  • 避免NG小提醒:別忘了 done(),也別亂叫它,不然動效會大亂套!

這篇分享能讓我們一步步玩轉動效,小技巧掌握後,未來動效會越來越順手,動起來輕鬆又俐落哦!🎨✨🚀


上一篇
Day06 Vue.js 簡單迷人的網頁動態效果 - 過渡類別篇
下一篇
Day08 Vue.js 簡單迷人的網頁動態效果 - TransitionGroup 篇
系列文
創意前端設計:用 Vue.js 打造 30 個互動實用功能15
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言